package com.moli.service.impl;

import com.moli.domain.ResponseResult;
import com.moli.domain.entity.LoginUser;
import com.moli.domain.entity.User;
import com.moli.domain.vo.BlogUserLoginVo;
import com.moli.domain.vo.UserInfoVo;
import com.moli.service.BlogLoginService;
import com.moli.utils.BeanCopyUtils;
import com.moli.utils.JwtUtil;
import com.moli.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @Author： XC
 * @Date： 2023-06-04 09:23
 * @Description： 用户登录实现类
 */
@Service
public class BlogLoginServiceImpl implements BlogLoginService {

	@Autowired
	private AuthenticationManager authenticationManager;

	@Autowired
	private RedisCache redisCache;

	@Override
	public ResponseResult login(User user) {
		UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(),user.getPassword());
		Authentication authenticate = authenticationManager.authenticate(authenticationToken);
		//1.判断是否认证通过，没通过给出对应的提示
		if(Objects.isNull(authenticate)){
			throw new RuntimeException("用户名或密码错误");
		}
		//2.获取userid 生成token
		//getPrincipal()，最重要的身份信息，大部分情况下返回的是UserDetails接口的实现类，也是框架中的常用接口之一。
		//authentication.getPrincipal()返回了一个Object，将Principal强转成了Spring Security中最常用的UserDetails，
		// 这在Spring Security中非常常见，接口返回Object，使用instanceof判断类型，强转成对应的具体实现类。
		LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
		//断点打在if(Objects.isNull(authenticate)){   这行，就知道 Principal里存放着用户信息，包括用户id，所以用Principal获取用户id

		String userId = loginUser.getUser().getId().toString();  //long类型 转成 字符串的形式
		String jwt = JwtUtil.createJWT(userId);
		//3.把用户信息(对象)存入redis  以键值对的方式
		redisCache.setCacheObject("bloglogin:"+userId,loginUser);

		//4.把token和userinfo封装 返回
		//把User转换成UserInfoVo(Bean的拷贝)
		UserInfoVo userInfoVo = BeanCopyUtils.copyBean(loginUser.getUser(), UserInfoVo.class);
		//响应体的两个值  token：就是jwt，userinfo：User转换成UserInfoVo
		BlogUserLoginVo vo = new BlogUserLoginVo(jwt,userInfoVo);
		return ResponseResult.okResult(vo);
	}

	@Override
	public ResponseResult logout() {
		//1.获取token 解析获取userid(从SecurityContextHolder中获取)
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		LoginUser loginUser = (LoginUser) authentication.getPrincipal();
		//2.获取userid
		Long userId = loginUser.getUser().getId();
		//3.删除redis中的用户信息
		redisCache.deleteObject("bloglogin:"+userId);
		return ResponseResult.okResult();
	}
}